import {toRaw, unref} from 'vue';

let timestamp = new Date().valueOf();
let count = 0;

function guidRandom(): string {
  return 'xxxxxxxxx'.replace(/[xy]/g, function (c) {
    let r = Math.random() * 16 | 0,
      v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

export function guid(): string {
  let currTimestamp = new Date().valueOf();
  if (currTimestamp - timestamp > 1000) {
    timestamp = new Date().valueOf();
    count = 0;
  }
  let countStr = ++count + '';
  while (countStr.length < 10) countStr = '0' + countStr;
  return currTimestamp + '' + countStr + guidRandom();
}

export function stopPropagation(e: any) {
  e.preventDefault();
  e.stopPropagation();
}

export function resolveErrorMessage(e: any) {
  if (!e || !e.response || !e.response.statusText) {
    return JSON.stringify(e);
  }
  return e.response.statusText;
}

export function resolveSort(list: any[]) {
  if (!list || list.length <= 0) return list;
  for (let i = 0; i < list.length; i++) {
    list[i].sort = i + 1;
  }
  return list;
}

export function mergeObject(src: any, dist: any): any {
  if (!src) return {};
  if (!dist) dist = {};
  for (const key in src) {
    dist[key] = src[key];
  }
  return dist;
}

export function findItemFromTrees(trees: any[], key: string, keyName = 'id'): any {
  return doFindItemFromTrees(trees, key, keyName);
}

function doFindItemFromTrees(trees: any[], key: string, keyName = 'id'): any {
  if (!trees || trees.length <= 0) return null;
  for (let i = 0; i < trees.length; i++) {
    let tree = trees[i];
    if (tree[keyName] === key) return tree;
    let res = doFindItemFromTrees(tree.children, key, keyName);
    if (res) return res;
  }
  return null;
}

export function listToTrees(list: any[]): any[] {
  let addedMap: any = {};
  for (let i = 0; i < list.length; i++) {
    let item = list[i];
    if (!item.parentId) continue;

    let index = list.findIndex(m => m.id === item.parentId);
    if (index !== -1) {
      let parent = list[index];
      if (!parent.children) parent.children = [];
      parent.children.push(item);
      addedMap[item.id] = '11';
    }
  }
  let res = [];
  for (let i = 0; i < list.length; i++) {
    let item = list[i];
    if (addedMap[item.id]) {
      continue;
    }
    res.push(item);
  }
  for (let i = 0; i < list.length; i++) {
    if (!list[i].children || list[i].children.length <= 0) {
      delete list[i].children;
      list[i].isLeaf = true;
    }
  }
  return res;
}

export function treesToList(trees: any[]): any[] {
  let res: any[] = [];
  doTreesToList(trees, res);
  resolveSort(res);
  return res;
}

function doTreesToList(trees: any[], res: any[]): void {
  if (!trees) return;
  for (let i = 0; i < trees.length; i++) {
    let tree = trees[i];
    res.push(tree);
    let children = tree.children;
    doTreesToList(children, res);
  }
}

export function findListTitle(key: string, list: any[], titleName = 'title', keyName = 'id') {
  if (!list || !key) return null;
  for (let i = 0; i < list.length; i++) {
    if (list[i][keyName] === key) return list[i][titleName];
  }
  return null;
}

export function isEmpty(obj: any) {
  if (obj === undefined || obj === null || obj === '') return true;
  if (Array.isArray(obj) && obj.length <= 0) return true;
  return false;
}

export function isEmptyThrow(obj: any, message: string) {
  if (isEmpty(obj)) throw new Error(message);
}

export function isNotEmpty(obj: any) {
  return !isEmpty(obj);
}

export function handleLikeParam(str: string) {
  if (isEmpty(str)) return undefined;
  return `%${str}%`;
}

export const required = {required: true, message: '此项为必填项', trigger: 'change'};

//根据数据字段，对森林排序
export function treesSort(treeNodes: any[], orderField = 'targetOrder', children = 'children') {
  if (treeNodes && treeNodes.length) {
    treeNodes.sort((a, b) => a[orderField] - b[orderField]);
    for (let i = 0; i < treeNodes.length; i++) {
      let tree = treeNodes[i];
      treeForeach(tree, (treeNode: any) => {
        if (treeNode[children] && treeNode[children].length)
          treeNode[children].sort((a:any, b:any) => a[orderField] - b[orderField]);
      }, false, children);
    }
  }
}

//遍历树
export function treeForeach(treeNode: any, callback: any, preOrder = true, children = 'children', parent = null, path: any[] = []) {
  if (treeNode) {
    path.push(treeNode);
    if (callback && preOrder) callback(treeNode, parent, path);
    if (treeNode[children] && treeNode[children].length)
      for (let i = 0; i < treeNode[children].length; i++)
        treeForeach(treeNode[children][i], callback, preOrder, children, treeNode, path);
    if (callback && !preOrder) callback(treeNode, parent, path);
    path.pop();
  }
}

//遍历森林
export function treesForeach(treeNodes: any[], callback: any, preOrder = true, children = 'children', path = []) {
  if (treeNodes && treeNodes.length)
    for (let i = 0; i < treeNodes.length; i++)
      treeForeach(treeNodes[i], callback, preOrder, children, null, path);
}

//数组转化成森林
export function listToTree(list: any[], parentKey = 'parentId'): any[] {
  let map: any = {}, tree: any[] = [];
  //list转换成map
  for (let i = 0; i < list.length; i++) map[list[i].key] = list[i];
  for (let i = 0; i < list.length; i++) {
    //存储没有父节点的列表（根节点）
    if (!list[i][parentKey] || list[i][parentKey] === '' || !map[list[i][parentKey]]) tree.push(list[i]);
    if (map[list[i][parentKey]]) {
      //如果存在父节点
      if (!map[list[i][parentKey]].children) map[list[i][parentKey]].children = [];
      map[list[i][parentKey]].children.push(list[i]);
    }
  }
  return tree;
}


export const pageOptions = [10, 20, 30, 50, 100];

export function resolveOrderConfig(sortConfig: any) {
  if (isEmpty(sortConfig) || isEmpty(sortConfig.prop) || isEmpty(sortConfig.order)) return {};
  return {
    _orderBy: sortConfig.prop,
    _order: sortConfig.order === 'descending' ? 'desc' : 'asc',
  };
}

export function resolvePagination(pagination: any) {
  return {
    current: pagination.current + '',
    size: pagination.size + '',
  };
}

export function canPreview(ext: string) {
  if (isEmpty(ext)) return false;
  ext = ext.toLocaleLowerCase();
  return ['jpg', 'png', 'svg', 'pdf'].findIndex(a => a === ext) !== -1;
}


export function handleBlurSearch(data: any, ...properties: any[]) {
  if (isEmpty(data)) return;
}

export function real(obj: any) {
  obj = toRaw(obj);
  obj = unref(obj);
  return obj
}
